import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Types;
import java.util.ArrayList;
import javax.swing.table.*; 


/** an immutable table model built from getting 
		metadata about a table in a jdbc database 
 */ 
public class GenericTableModel extends AbstractTableModel {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private Object[][] contents;
	private String[] columnNames;
	@SuppressWarnings("rawtypes")
	private Class[] columnClasses;

	public GenericTableModel (Connection conn,String tableName)
			throws SQLException {
		super();
		getTableContents (conn, tableName);

	}
	protected void getTableContents (Connection conn,
			String tableName)
					throws SQLException {
		DatabaseMetaData meta = (DatabaseMetaData) conn.getMetaData();
		ResultSet results =
				meta.getColumns (null, null, tableName, null) ;
		ArrayList<String> colNamesList = new ArrayList<String>();
		ArrayList<Class<?>> colClassesList = new ArrayList<Class<?>>();
		while (results.next()) {
			colNamesList.add (results.getString ("COLUMN_NAME")); 
			int dbType = results.getInt ("DATA_TYPE");
			switch (dbType) {
			case Types.INTEGER:
				colClassesList.add (Integer.class); break; 
			case Types.FLOAT:
				colClassesList.add (Float.class); break; 
			case Types.DOUBLE: 
			case Types.REAL:
				colClassesList.add (Double.class); break; 
			case Types.DATE: 
			case Types.TIME: 
			case Types.TIMESTAMP:
				colClassesList.add (java.sql.Date.class); break; 
			default:
				colClassesList.add (String.class); break; 
			}; 
		}
		columnNames = new String [colNamesList.size()];
		colNamesList.toArray (columnNames);
		columnClasses = new Class [colClassesList.size()];
		colClassesList.toArray (columnClasses);
		Statement statement =
				conn.createStatement ();
		results = statement.executeQuery ("SELECT * FROM " +
				tableName);
		ArrayList<Object[]> rowList = new ArrayList<Object[]>();
		while (results.next()) {
			ArrayList<Object> cellList = new ArrayList<Object>(); 
			for (int i = 0; i<columnClasses.length; i++) { 
				Object cellValue = null;
				if (columnClasses[i] == String.class) 
					cellValue = results.getString (columnNames[i]); 
				else if (columnClasses[i] == Integer.class) 
					cellValue = new Integer ( 
							results.getInt (columnNames[i])); 
				else if (columnClasses[i] == Float.class) 
					cellValue = new Float ( 
							results.getInt (columnNames[i])); 
				else if (columnClasses[i] == Double.class) 
					cellValue = new Double ( 
							results.getDouble (columnNames[i]));
				else if (columnClasses[i] == java.sql.Date.class) 
					cellValue = results.getDate (columnNames[i]); 
				else 
					System.out.println ("Can't assign " + 
							columnNames[i]);
				cellList.add (cellValue);
			}
			Object[] cells = cellList.toArray();
			rowList.add (cells);
		}
		contents = new Object[rowList.size()] [];
		for (int i=0; i<contents.length; i++)

			contents[i] = rowList.get (i);
		results.close();
		statement.close();

	}
	public int getRowCount() {
		return contents.length;
	}

	public int getColumnCount() {
		if (contents.length == 0)
			return 0;
		else
			return contents[0].length;
	}

	public Object getValueAt (int row, int column) {
		return contents [row][column];
	}
	 public String getColumnName(int col) {
		    return columnNames[col];
	 }
	
}